﻿#include "tcpserver.h"
#include "system/systemlogfile.h"
#include <QDebug>

namespace Common {

	TcpServer::TcpServer(QObject *parent)
		: QObject(parent)
		, m_pTcpServer(new QTcpServer(this))
	{
		connect(m_pTcpServer, &QTcpServer::newConnection, this, &TcpServer::slotTcpNewConnection);
	}

	TcpServer::~TcpServer()
	{
		if (m_pTcpServer != NULL)
		{
			m_pTcpServer->close();
			delete m_pTcpServer;
			m_pTcpServer = NULL;
		}
	}

	QTcpServer *TcpServer::getTcpServer()
	{
		return m_pTcpServer;
	}

	bool TcpServer::createServer(QString strIp, int port)
	{
		if (port <= 0 || port > USHRT_MAX || strIp.isEmpty())
		{
			return false;
		}

		QHostAddress address;
		if (strIp == QString("Any"))
		{
			address = QHostAddress::Any;
		}
		else {
			address = QHostAddress(strIp);
		}

		bool t_listen = false;
		t_listen = m_pTcpServer->listen(address, port);
		t_listen = m_pTcpServer->isListening();
		return t_listen;
	}

	void TcpServer::closeServer()
	{
		m_pTcpServer->close();
	}

	bool TcpServer::isListening()
	{
		return m_pTcpServer->isListening();
	}

	bool TcpServer::sendMsgToClient(QString ip, int port, QTcpSocket *t_tcpSocket, QByteArray buff)
	{
		Q_UNUSED(ip)
		Q_UNUSED(port)

		if (t_tcpSocket == nullptr)
		{
			return false;
		}

		t_tcpSocket->write(buff);
		return t_tcpSocket->flush();
	}

	/**
	 * @brief 在Tcp服务器每次新连接可用时发出 信号
	 * @note 该函数用于获取连接的客户端信息
	 */
	void TcpServer::slotTcpNewConnection()
	{
		// 如果有新的连接就取出
		while (m_pTcpServer->hasPendingConnections())
		{
			//nextPendingConnection返回下一个挂起的连接作为已连接的QTcpSocket对象
			//套接字是作为服务器的子级创建的，这意味着销毁QTcpServer对象时会自动删除该套接字。
			//最好在完成处理后显式删除该对象，以避免浪费内存。
			//返回的QTcpSocket对象不能从另一个线程使用，如有需要可重写incomingConnection().
			QTcpSocket *t_tcpSocket = m_pTcpServer->nextPendingConnection();

			QString t_clientIp = t_tcpSocket->peerAddress().toString();
			int t_clientPort = t_tcpSocket->peerPort();
			
			emit signalConnectedClient(t_tcpSocket, t_clientIp, t_clientPort);
			
			QString strMes = QString("Client IP:%1 %2 connected to Server").arg(t_clientIp).arg(t_clientPort);
			SYSTEMLOG_ERROR(strMes.toStdString().data());
			emit signalServerLog(QString("Client IP:%1 %2 connected to Server").arg(t_clientIp).arg(t_clientPort));

			// 连接断开，销毁socket对象，这是为了开关server时socket正确释放
			connect(t_tcpSocket, &QTcpSocket::disconnected, [this, t_tcpSocket]
			{
				QString t_clientIp = t_tcpSocket->peerAddress().toString();
				int t_clientPort = t_tcpSocket->peerPort();
			
				emit signalDisconnectedClient(t_tcpSocket, t_clientIp, t_clientPort);
				
				QString strMes = QString("Client IP:%1 %2 disconnected to Server").arg(t_clientIp).arg(t_clientPort);
				SYSTEMLOG_ERROR(strMes.toStdString().data());
				emit signalServerLog(QString("Client IP:%1 %2 disconnected to Server").arg(t_clientIp).arg(t_clientPort));

				t_tcpSocket->deleteLater();
			});

			// 状态
			connect(t_tcpSocket, &QTcpSocket::stateChanged, [this, t_tcpSocket]
			{
				QString t_clientIp = t_tcpSocket->peerAddress().toString();
				int t_clientPort = t_tcpSocket->peerPort();

				QAbstractSocket::SocketState state = t_tcpSocket->state();
				switch (state)
				{
					//[] socket 未连接
				case QAbstractSocket::UnconnectedState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::UnconnectedState");
					break;
				}
				//[]套接字正在执行主机名查找。
				case QAbstractSocket::HostLookupState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::HostLookupState");
					break;
				}
				//[]  套接字已开始建立连接。
				case QAbstractSocket::ConnectingState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::ConnectingState");
					break;
				}
				//[] 建立连接
				case QAbstractSocket::ConnectedState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::ConnectedState");
					break;
				}
				//[]  套接字绑定到一个地址和端口
				case QAbstractSocket::BoundState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::BoundState");
					break;
				}
				//[] 套接字即将关闭
				case QAbstractSocket::ClosingState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::ClosingState");
					break;
				}
				//[] 监听状态
				case QAbstractSocket::ListeningState:
				{
					SYSTEMLOG_ERROR("QAbstractSocket::ListeningState");
					break;
				}
				default:
					break;
				}
			});

			// 读取信息
			connect(t_tcpSocket, &QTcpSocket::readyRead, [this, t_tcpSocket]
			{
				// 客户端Ip 和 端口
				QString t_clientIp = t_tcpSocket->peerAddress().toString();
				int t_clientPort = t_tcpSocket->peerPort();

				QByteArray t_dataInfo = t_tcpSocket->readAll();
				if (!t_dataInfo.isEmpty())
				{
					emit signalRecvClientMsg(t_tcpSocket, t_clientIp, t_clientPort, t_dataInfo);
				}
			});
		}
	}

}//namespace Common
